#ifndef CODEGEN_H
#define CODEGEN_H

#include "AstNode.h"
#include "Visitor.h"
#include <string>

class CodeGenerater : public AstVisitor {
private:
    int StackTop = 0;
    int Sequece = 0;  // 多个if\while的区分

    // 64位汇编，当参数少于7个时， 参数从左到右放入寄存器: rdi, rsi, rdx, rcx, r8, r9。
    const char *Reg8[6] = {"%dil", "%sil", "%dl", "%cl", "%r8b", "%r9b"};
    const char *Reg16[6] = {"%di", "%si", "%dx", "%cx", "%r8w", "%r9w"};
    const char *Reg32[6] = {"%edi", "%esi", "%edx", "%ecx", "%r8d", "%r9d"};
    const char *Reg64[6] = {"%rdi", "%rsi", "%rdx", "%rcx", "%r8", "%r9"};
    std::string CurrentFuncName;    // 记录当前函数名
public:

    CodeGenerater() {}
    
    void VisitProgramNode(ProgramAstNode *node) override;
    void VisitFunctionNode(FunctionNode *node) override;
    void VisitExprStatmNode(ExprStatmNode *node) override;
    void VisitFuncCallNode(FuncCallNode *node) override;
    void VisitDeclarationStatmNode(DeclarationStatmNode *node) override;
    void VisitIfStatmNode(IfStatmNode *node) override;
    void VisitWhileStatmNode(WhileStatmNode *node) override;
    void VisitForStatmNode(ForStatmNode *node) override;
    void VisitReturnStatmNode(ReturnStatmNode *node) override;
    void VisitBlockStatmNode(BlockStatmNode *node) override;
    void VisitAssignExprNode(AssignExprNode *node) override;
    void VisitBinaryNode(BinaryAstNode *node) override;
    void VisitUnaryNode(UnaryAstNode *node) override;
    void VisitConstantNode(ConstantAstNode *node) override;
    void VisitSizeofNode(SizeofNode *node) override;
    void VisitVarNode(VarAstNode *node) override;

    void Push();
    void Pop(const char *reg);

    void LoadMemToReg(std::shared_ptr<Type> ty);
    void SaveRegToMem(std::shared_ptr<Type> ty);

    void GenAddr(AstNode *node);
    int AlignTo(int size, int align);
};

#endif // !CODEGEN_H